<template>
  <div>

    <el-form ref="form" :label-width="labelWidth" :model="data" :rules="rules">

      <el-row :gutter="10" style="display: flex; flex-wrap: wrap; ">
        <el-col
          v-for="(item,index) in definition"
          v-if="booleanFun(item.if)"
          v-show="booleanFun(item.show)"
          :key="index"
          v-has-permi="item.hasPer"
          :span="item.span || span"
          size="mini"
        >
          <el-form-item
            v-if="item.type!=='divider'"
            :label="item.label"
            :prop="item.prop || item.beginName || 'beginDate'"
            :label-width="item.labelWidth || labelWidth"
          >

            <a-input
              v-if="(item.type || 'input') === 'input'"
              :prop="item.prop"
              :label="item.label"
              :data.sync="data[item.prop]"
              :item-type="item.itemType"
              :placeholder="item.placeholder"
              :width="item.width"
              :readonly="item.readonly"
              :disabled="getDisabled(item)"
              :clearable="getClearable(item)"
              :min="item.min"
              :max="item.max"
              :step="item.step"
            />

            <a-select
              v-else-if="item.type === 'select'"
              :prop="item.prop"
              :label="item.label"
              :data.sync="data[item.prop]"
              :placeholder="item.placeholder"
              :filterable="item.filterable"
              :multiple="item.multiple"
              :key-name.sync="item.keyName"
              :label-name.sync="item.labelName"
              :dict="item.dict"
              :option="item.option"
              :binding="item.binding"
              :width="item.width"
              :disabled="getDisabled(item)"
              :clearable="getClearable(item)"
            />

            <a-radio
              v-else-if="item.type === 'radio'"
              :prop="item.prop"
              :label="item.label"
              :data.sync="data[item.prop]"
              :key-name.sync="item.keyName"
              :label-name.sync="item.labelName"
              :dict="item.dict"
              :option="item.option"
              :binding="item.binding"
              :disabled="getDisabled(item)"
            />

            <a-checkbox
              v-else-if="item.type === 'checkbox'"
              :prop="item.prop"
              :label="item.label"
              :data.sync="data[item.prop]"
              :key-name.sync="item.keyName"
              :label-name.sync="item.labelName"
              :dict="item.dict"
              :option="item.option"
              :binding="item.binding"
              :disabled="getDisabled(item)"
            />

            <a-date-picker
              v-else-if="item.type === 'datePicker'"
              :prop="item.prop"
              :label="item.label"
              :data.sync="data[item.prop]"
              :item-type="item.itemType"
              :format="item.format"
              :picker-options="item.pickerOptions"
              :placeholder="item.placeholder"
              :width="item.width"
              :disabled="getDisabled(item)"
              :readonly="item.readonly"
              :clearable="getClearable(item)"
            />

            <a-date-range
              v-else-if="item.type === 'dateRange'"
              :label="item.label"
              :begin-time.sync="data[item.beginName || 'beginTime']"
              :end-time.sync="data[item.endName || 'endTime']"
              :width="item.width"
              :disabled="getDisabled(item)"
              :readonly="item.readonly"
              :clearable="getClearable(item)"
            />

            <!--
              插槽:
                 slot:      插槽命名
                 <template v-slot:prop> {{ 'demo' }} </template>
             -->
            <slot v-else-if="item.type === 'slot'" :name="item.prop"/>

          </el-form-item>

          <div v-else>
            <div v-if="index!==0" style="padding-top: 25px"/>
            <span>{{ item.label }}</span>
            <el-divider/>
          </div>

        </el-col>

        <el-col v-if="notNull(query) || notNull(reset)" :span="6">
          <div style="margin-bottom: 15px; padding-top: 4px">
            <el-button v-if="notNull(query)" icon="el-icon-search" size="mini" type="primary" @click="query()">
              搜索
            </el-button>
            <el-button v-if="notNull(reset)" icon="el-icon-refresh" size="mini" @click="reset()">
              重置
            </el-button>
          </div>
        </el-col>

      </el-row>
    </el-form>

  </div>
</template>

<script>
import {booleanFun, notNull} from '@/components/FlyElement/common'
import AInput from '@/components/FlyElement/form/aInput.vue'
import ASelect from '@/components/FlyElement/form/aSelect.vue'
import ARadio from '@/components/FlyElement/form/aRadio.vue'
import ACheckbox from '@/components/FlyElement/form/aCheckbox.vue'
import ADatePicker from '@/components/FlyElement/form/aDatePicker.vue'
import ADateRange from '@/components/FlyElement/form/aDateRange.vue'

export default {
  name: 'AForm',
  components: {
    AInput, ASelect, ARadio, ACheckbox, ADatePicker, ADateRange
  },
  props: {
    // 表单定义
    definition: {
      type: Array,
      required: true
    },
    // 表单数据
    data: {
      type: Object,
      required: true
    },
    // 数据校验
    rules: {
      type: Object
    },
    // 全局span
    span: {
      type: Number,
      default: 24
    },
    // 全局可清空
    clearable: {
      type: Boolean,
      default: true
    },
    // 全局禁用
    disabled: {
      type: Boolean,
      default: false
    },
    // 搜索方法
    query: {
      type: Function
    },
    // 重置方法
    reset: {
      type: Function
    }
  },
  computed: {
    labelWidth: {
      get() {
        let MaxLength = 0
        this.definition.forEach(item => {
          if (item.labelWidth || item.type === 'divider') {
            return
          }

          if (item.label) {
            let itemLength = 0
            Array.from(item.label).map((char) => {
              const number = char.charCodeAt(0)
              // 双字节字符
              if (number > 255) {
                itemLength += 20
              }
              // 大写字母
              else if (number > 65 && number < 90) {
                itemLength += 10
              }
              // 小写字母和符号
              else {
                itemLength += 8
              }
            })
            itemLength > MaxLength && (MaxLength = itemLength)
          }
        })
        return MaxLength + 'px'
      }
    }
  },
  methods: {
    booleanFun,
    notNull,
    getClearable(item) {
      return item.clearable === undefined ? this.clearable : this.booleanFun(item.clearable)
    },
    getDisabled(item) {
      return item.disabled === undefined ? this.disabled : this.booleanFun(item.disabled)
    },
    /**
     * 以下为提供父组件调用的方法
     */
    // 验证表单
    validate() {
      let flag
      this.$refs.form.validate((valid) => {
        flag = valid
      })
      return flag
    },
    // 清空验证错误
    clearValidate() {
      this.$refs.form.clearValidate()
    }
  }
}
</script>

<style scoped>
.el-form-item {
  margin-bottom: 16px;
}

.el-divider--horizontal {
  display: block;
  height: 1px;
  width: 100%;
  margin-top: 3px;
  margin-bottom: 10px;
}
</style>
